#ifndef CLCOMFUNCS_H
#define CLCOMFUNCS_H

#include <vector>
#include <string>
#include <map>
#include <QtCore/qglobal.h>
#include "CLComLibrarys_global.h"
//CLCOMLIBRARYS_EXPORT

using namespace std;

struct  CLCOMLIBRARYS_EXPORT _tagJasonValue
{
    vector<string>	_valueVec;	//值内容
    int		_type;				//0 单值 1结构体 2数组
    _tagJasonValue& operator=(_tagJasonValue& other);
};
enum E_ARG_TYPE
{
    E_ARG_TYPE_NO = 0,
    E_ARG_TYPE_SHORT,
    E_ARG_TYPE_INT,
    E_ARG_TYPE_LONG,
    E_ARG_TYPE_LONGLONG,
    E_ARG_TYPE_FLOAT,
    E_ARG_TYPE_DOUBLE,
    E_ARG_TYPE_CHARS,
};
typedef struct  CLCOMLIBRARYS_EXPORT _tagARGNode
{
    E_ARG_TYPE	aType;
    void*		pValue;

    _tagARGNode();
    _tagARGNode& operator=(const _tagARGNode& other);
}ARGNODE;

class CLCOMLIBRARYS_EXPORT CLComFuncs
{
public:
    CLComFuncs();
    ~CLComFuncs();

    static qint64 min(qint64 a, qint64 b);
    static qint64 max(qint64 a, qint64 b);

    // 判断是否为数字，如果是并转化成double
    static bool IsNumber_f(const char* sourceStr, double& outDouble);
    // 判断字符串是不是数字，如果是数字则转成数字
    static bool IsNumber_i(const char* sourceStr, qint64& outNumberInt);
    // 判断字符串是否数字，如果是数字则转成字符串，如果没达到minlen长度，则前面加0
    static bool Num2String(char* outString, int& outLen, qint64 inNumber, int minLen);
    // 删除字符串ousrcestr中所有的delstr
    static bool DelSubStr(char* sourceStr, const char* delStr);
    // 将sourcestr中的oldstr替换为newstr
    static bool ReplaceSubstr(string& sourceStr, const string& oldStr, const string& newStr);
    // 字符串如果有大写字母则全转小写
    static bool LowerCaseString(string& strInput);
    // 判断是否为中文
    static bool IsChinese(char inChar);
    //字符串小写转大写
    static bool CapCaseString(string& strInput);
    // 查找ssrouce中的sfind，intstart为其实查找地址， forward为真则正向查找，false为反向查找， 返回值为-1为没找到
    static qint64 FindMix(const string& sSource, const string& sfind, qint64 intStart, bool forward);
    // 删除strsource中从strstart到strend之间的字符串，知道end位置，如果isclear为真则删除所有的，如果为false则删除第一个, 如果strstart为空，则删除从头到strend的字符串，如果strend为空，则删除strstart字符串
    //返回值判断是否删除过
    static bool ClearString(string& strSource, const string& strStart, const string& strEnd, bool isClearAll, int end);
    // 从source中截取size个字节，如果source的长度不够则不截取，该函数为了截取中文字符的，防止将中文字符分开
    static bool TruncateString(string& strSource, int size);
    // 判断是否是全角数字和字母
    static bool IsSBCCase(char cur1, char cur2);
    // 是否为字符
    static bool IsLetter(char ch);
    //是否为数字
    static bool IsNumber(char ch);
    /*过滤字符串，也就是从start开始，如果遇到了spliters中的字符，则过，直到遇到一个不是为止
    *source 源字符串
    *beSplited  要过滤掉得字符，每个字符用逗号隔开，如："-,_,－"
    *spliter    用来分割的字符。如上面的,
    *start     从什么位置开始过滤
    *返回最终不是的为止
    * forward为方向
    */
    static size_t FilterString(string& source, string beSplited, string spliter, qint64 start, bool forward);

    /*把一个string分成多个string
    *vp  存放结果字符串的vector
    *spliter  分隔字符串的分隔符
    *source    被分割的字符串
    */
    static void SplitString(vector<string>* vp, string spliter, string& source, bool fillNull);
    static void ExtractString(vector<string>* vp, string startspliter, string endspliter, string& source);
    /*判断2个字符串是否相似，similarPercent为判断相似的百分比
    *判断的规则是 短串是长串的字串的时候才进行判断，
    *返回的百分比是长串字节数和短串的字节数的比值
    */
    static float SimilarString(string& str1, string& str2);

    //日志打印函数fileName是日志输出的文件名，路径是当前路径下LOG文件夹中
    //logContent为日志内容
    //提取文件中含有words的哪一行，写入outfilenames文件中
    static void ExtractByWords(const string& fileName, const string& words, const string& outFileName);

    //宽字节转窄字节，32-126
    static bool ConvertWidthToHalf(string& str);
    //窄字节转宽字节，32-126
    static bool ConvertHalfToWidth(string& str, vector<int>& v_exceptChars);
    static bool ConvertHalfToWidth(string& str);

    static void GetNumber(string inputstr, char splitec, qint64* outputNumber);//字符splitec之后的数字
    static void GetNumber(string inputstr, char splitec, int* outputNumber);//字符splitec之后的数字
    static void GetString(string inputstr, char splitec, string& outputStr);//字符splitec之后的字符串
    static void GetOX(string inputstr, char splitec, bool& outputNumber);//字符splitec之后的是否为真

    //将十进制的数转16进制字符串
    static bool Decimal2Hex(qint64 inputNumber, string& outputNumber);
    //十六进制转10进制
    static bool Hex2Decimal(const string& inputstr, qint64& outputNumber);

    //倒转字符串
    static bool ReverseString(string& inputstr);

    static char *rtrim(char *buffer);
    static char *ltrim(char *buffer);
    static char *trim(char* in);

    static bool FloadIsZero(double f);
    static size_t widechar2multibyte(const wchar_t* pwchar, char** szstr);
    static size_t multibyte2widechar(const char* szstr, wchar_t** pwchar);
    static bool IsWow64();
    static bool FindFirstFileExists(const char* lpPath, const char* suffix);
    static bool FilePathExists(const char* lpPath);
    static bool FileIsExist(const char* filefullname);

    static bool FindAllFile(
            const char* path,
            const char* suffix,
            const char* filenamehavestr,
            vector<string>& vecfiles,
            bool recursion);

    static bool  Make_dir(string path);
    static void Char2HexString(char* source, size_t size);

    static bool LogicIP(const char* ipstr);
    static bool SetWorkDir2ExeDir();
    static bool GetLocation(string& dir);

    static void CodeString(string& source);
    static void DecodeString(string& source);

    static bool ParseJason(string srcstr, map<string, _tagJasonValue>& columnmap);

    static bool Struct2NumString(const char* srcstr, int len, string& outstr);
    static bool NumString2Struct(string& srcstr, char* outstr, size_t& outlen);

    static bool FileNameIsLogic(const char* filename);
    //图片处理

    //打印长度控制
    static int SprintfSafe(char* outBuffer, quint64 nSize, vector<_tagARGNode>& vec);
    //拼接字符串
    static string FormatString(int nMaxSize, const char* szFormat, ...);

    //获取路径下所有文件
    static void SearchFiles(string path, bool bfindDir, vector<string>& vec);
    static bool CopyFolder(const char* lpszTo, const char* lpszFrom, bool override);
};

#endif // CLCOMFUNCS_H
